home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / mail / Mutt089src.lha / Mutt-0.89i-AMIGA / src / compose.c < prev    next >
C/C++ Source or Header  |  1998-01-28  |  20KB  |  808 lines

  1. /*
  2.  * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
  3.  * 
  4.  *     This program is free software; you can redistribute it and/or modify
  5.  *     it under the terms of the GNU General Public License as published by
  6.  *     the Free Software Foundation; either version 2 of the License, or
  7.  *     (at your option) any later version.
  8.  * 
  9.  *     This program is distributed in the hope that it will be useful,
  10.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *     GNU General Public License for more details.
  13.  * 
  14.  *     You should have received a copy of the GNU General Public License
  15.  *     along with this program; if not, write to the Free Software
  16.  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */ 
  18.  
  19. #include "mutt.h"
  20. #include "mutt_curses.h"
  21. #include "mutt_menu.h"
  22. #include "send.h"
  23. #include "rfc1524.h"
  24. #include "mime.h"
  25. #include "attach.h"
  26.  
  27. #include <string.h>
  28. #include <sys/stat.h>
  29. #include <sys/wait.h>
  30. #include <unistd.h>
  31. #include <stdlib.h>
  32.  
  33. #define CHECK_COUNT if (idxlen == 0) { mutt_error ("There are no attachments."); break; }
  34.  
  35. #define HDR_TO 1
  36. #define HDR_CC 2
  37. #define HDR_BCC 3
  38. #define HDR_SUBJECT 4
  39. #define HDR_REPLYTO 5
  40. #define HDR_FCC 6
  41.  
  42. #ifdef _PGPPATH
  43. #define HDR_PGP 7
  44. #endif
  45.  
  46. /* where to start printing the attachments */
  47. #define HDR_ATTACH 10
  48.  
  49. #define HDR_XOFFSET 10
  50.  
  51. void snd_entry (char *b, size_t blen, MUTTMENU *menu, int num)
  52. {
  53.   char t[SHORT_STRING], size[SHORT_STRING];
  54.   char tmp[_POSIX_PATH_MAX];
  55.   BODY *m;
  56.   ATTACHPTR **idx = (ATTACHPTR **) menu->data;
  57.   struct stat finfo;
  58.  
  59.   m = idx[num]->content;
  60.  
  61.   if (m->filename && m->filename[0])
  62.   {
  63.     if (stat (m->filename, &finfo) != -1)
  64.       mutt_pretty_size (size, sizeof (size), finfo.st_size);
  65.     else
  66.       strcpy (size, "0K");
  67.     strfcpy (tmp, m->filename, sizeof (tmp));
  68.   }
  69.   else
  70.   {
  71.     strcpy (size, "0K");
  72.     strcpy (tmp, "<no file>");
  73.   }
  74.   mutt_pretty_mailbox (tmp);
  75.  
  76.   snprintf (t, sizeof (t), "[%.7s/%.10s, %.6s, %s]",
  77.         TYPE (m->type), m->subtype, ENCODING (m->encoding), size);
  78.  
  79.   snprintf (b, blen, "%c%c%2d %-34.34s %s%s <%s>",
  80.         m->unlink ? '-' : ' ',
  81.         m->tagged ? '*' : ' ',
  82.         num + 1,
  83.         t,
  84.         idx[num]->tree ? idx[num]->tree : "",
  85.         tmp,
  86.         m->description ? m->description : "no description");
  87. }
  88.  
  89. #ifdef _PGPPATH
  90. #include "pgp.h"
  91.  
  92. static int pgp_send_menu (int bits)
  93. {
  94.   int c;
  95.   char *p;
  96.  
  97.   mvaddstr (LINES-1, 0, "(e)ncrypt, (s)ign, sign (a)s, (b)oth or (f)orget it? ");
  98.   clrtoeol ();
  99.   do
  100.   {
  101.     mutt_refresh ();
  102.     if ((c = mutt_getch ()) == ERR)
  103.       break;
  104.     if (c == 'a')
  105.     {
  106.       unset_option(OPTPGPCHECKTRUST);
  107.       if ((p = pgp_ask_for_key (PgpSecring, NULL, "Sign as: ", NULL, KEYFLAG_CANSIGN)))
  108.       {
  109.     snprintf (PgpSignAs, sizeof (PgpSignAs), "0x%s", p);
  110.     pgp_void_passphrase (); /* probably need a different passphrase */
  111.     free (p);
  112.     bits |= PGPSIGN;
  113.       }
  114.     }
  115.     else if (c == 'e')
  116.       bits |= PGPENCRYPT;
  117.     else if (c == 's')
  118.       bits |= PGPSIGN;
  119.     else if (c == 'b')
  120.       bits = PGPENCRYPT | PGPSIGN;
  121.     else if (c == 'f')
  122.       bits = 0;
  123.     else
  124.     {
  125.       BEEP ();
  126.       c = 0;
  127.     }
  128.   }
  129.   while (c == 0);
  130.   CLEARLINE (LINES-1);
  131.   mutt_refresh ();
  132.   return (bits);
  133. }
  134. #endif /* _PGPPATH */
  135.  
  136. static void draw_envelope (HEADER *msg, char *fcc)
  137. {
  138.   char buf[STRING];
  139.  
  140.   mvaddstr (HDR_TO, 0,      "      To: ");
  141.   buf[0] = 0;
  142.   rfc822_write_address (buf, sizeof (buf), msg->env->to);
  143.   printw ("%-*.*s", COLS-HDR_XOFFSET, COLS-HDR_XOFFSET, buf);
  144.  
  145.   mvaddstr (HDR_CC, 0,      "      Cc: ");
  146.   buf[0] = 0;
  147.   rfc822_write_address (buf, sizeof (buf), msg->env->cc);
  148.   printw ("%-*.*s", COLS-HDR_XOFFSET, COLS-HDR_XOFFSET, buf);
  149.  
  150.   mvaddstr (HDR_BCC, 0,     "     Bcc: ");
  151.   buf[0] = 0;
  152.   rfc822_write_address (buf, sizeof (buf), msg->env->bcc);
  153.   printw ("%-*.*s", COLS-HDR_XOFFSET, COLS-HDR_XOFFSET, buf);
  154.  
  155.   mvaddstr (HDR_SUBJECT, 0, " Subject: ");
  156.   if (msg->env->subject)
  157.     printw ("%-*.*s", COLS-HDR_XOFFSET, COLS-HDR_XOFFSET, msg->env->subject);
  158.   else
  159.     clrtoeol ();
  160.  
  161.   mvaddstr (HDR_REPLYTO, 0, "Reply-To: ");
  162.   if (msg->env->reply_to)
  163.   {
  164.     buf[0] = 0;
  165.     rfc822_write_address (buf, sizeof (buf), msg->env->reply_to);
  166.     printw ("%-*.*s", COLS - HDR_XOFFSET, COLS - HDR_XOFFSET, buf);
  167.   }
  168.   else
  169.     clrtoeol ();
  170.  
  171.   mvaddstr (HDR_FCC, 0,     "     Fcc: ");
  172.   addstr (fcc);
  173.  
  174. #ifdef _PGPPATH
  175.   mvaddstr (HDR_PGP, 0,     "     PGP: ");
  176.   if ((msg->pgp & (PGPENCRYPT | PGPSIGN)) == (PGPENCRYPT | PGPSIGN))
  177.     addstr ("Sign, Encrypt");
  178.   else if (msg->pgp & PGPENCRYPT)
  179.     addstr ("Encrypt");
  180.   else if (msg->pgp & PGPSIGN)
  181.   {
  182.     addstr ("Sign");
  183.     if (PgpSignAs[0])
  184.       printw (" as %s", PgpSignAs);
  185.   }
  186.   else
  187.     addstr ("Clear");
  188.   clrtoeol ();
  189. #endif /* _PGPPATH */
  190.  
  191.   mvaddstr (HDR_ATTACH-1, 0, "===== Attachments =====");
  192. }
  193.  
  194. static int edit_address_list (int line, ENVELOPE *env)
  195. {
  196.   char buf[HUGE_STRING] = ""; /* needs to be large for alias expansion */
  197.   ADDRESS **addr;
  198.   char *prompt;
  199.  
  200.   switch (line)
  201.   {
  202.     case HDR_TO:
  203.       prompt = "To: ";
  204.       addr = &env->to;
  205.       break;
  206.  
  207.     case HDR_CC:
  208.       prompt = "Cc: ";
  209.       addr = &env->cc;
  210.       break;
  211.  
  212.     case HDR_BCC:
  213.       prompt = "Bcc: ";
  214.       addr = &env->bcc;
  215.       break;
  216.  
  217.     case HDR_REPLYTO:
  218.       prompt = "Reply-To: ";
  219.       addr = &env->reply_to;
  220.       break;
  221.  
  222.     default:
  223.       return 0;
  224.   }
  225.  
  226.   rfc822_write_address (buf, sizeof (buf), *addr);
  227.   if (mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS) != 0)
  228.     return 0;
  229.  
  230.   mutt_free_address (addr);
  231.   mutt_parse_adrlist (addr, buf, "@");
  232.   *addr = mutt_expand_aliases (*addr);
  233.  
  234.   if (option (OPTNEEDREDRAW))
  235.   {
  236.     unset_option (OPTNEEDREDRAW);
  237.     return (REDRAW_FULL);
  238.   }
  239.  
  240.   /* redraw the expanded list so the user can see the result */
  241.   buf[0] = 0;
  242.   rfc822_write_address (buf, sizeof (buf), *addr);
  243.   move (line, HDR_XOFFSET);
  244.   printw ("%-*.*s", COLS - HDR_XOFFSET, COLS - HDR_XOFFSET, buf);
  245.  
  246.   return 0;
  247. }
  248.  
  249. static int delete_attachment (MUTTMENU *menu, short *idxlen, int x)
  250. {
  251.   ATTACHPTR **idx = (ATTACHPTR **) menu->data;
  252.   int y;
  253.  
  254.   menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
  255.  
  256.   if (x == 0 && menu->max == 1)
  257.   {
  258.     mutt_error ("You may not delete the only attachment.");
  259.     idx[x]->content->tagged = 0;
  260.     return (-1);
  261.   }
  262.  
  263.   for (y = 0; y < *idxlen; y++)
  264.   {
  265.     if (idx[y]->content->next == idx[x]->content)
  266.     {
  267.       idx[y]->content->next = idx[x]->content->next;
  268.       break;
  269.     }
  270.   }
  271.  
  272.   idx[x]->content->next = NULL;
  273.   idx[x]->content->parts = NULL;
  274.   mutt_free_body (&(idx[x]->content));
  275.   safe_free ((void **) &idx[x]->tree);
  276.   safe_free ((void **) &idx[x]);
  277.   for (; x < *idxlen - 1; x++)
  278.     idx[x] = idx[x+1];
  279.   menu->max = --(*idxlen);
  280.   
  281.   return (0);
  282. }
  283.  
  284. /* return values:
  285.  *
  286.  * 1    message should be postponed
  287.  * 0    normal exit
  288.  * -1    abort message
  289.  */
  290. int mutt_send_menu (HEADER *msg,   /* structure for new message */
  291.             char *fcc,     /* where to save a copy of the message */
  292.             size_t fcclen,
  293.             HEADER *cur)   /* current message */
  294. {
  295.   char helpstr[SHORT_STRING];
  296.   char buf[LONG_STRING];
  297.   char fname[_POSIX_PATH_MAX];
  298.   MUTTMENU *menu;
  299.   BODY *tmp;
  300.   ATTACHPTR **idx = NULL;
  301.   short idxlen = 0;
  302.   short idxmax = 0;
  303.   int i;
  304.   int r = -1;        /* return value */
  305.   int op = 0;
  306.   int loop = 1;
  307.   int fccSet = 0;    /* has the user edited the Fcc: field ? */
  308.  
  309.   idx = mutt_gen_attach_list (msg->content, &idxlen, &idxmax, 1);
  310.  
  311.   menu = mutt_new_menu ();
  312.   menu->menu = MENU_COMPOSE;
  313.   menu->offset = HDR_ATTACH;
  314.   menu->max = idxlen;
  315.   menu->make_entry = snd_entry;
  316.   menu->tag = mutt_tag_attach;
  317.   menu->title = "Compose";
  318.   menu->data = idx;
  319.  
  320.   helpstr[0] = 0;
  321.   mutt_make_help (buf, sizeof (buf), "Send  ", MENU_COMPOSE, OP_COMPOSE_SEND_MESSAGE);
  322.   strcat (helpstr, buf);
  323.   mutt_make_help (buf, sizeof (buf), "Abort  ", MENU_COMPOSE, OP_EXIT);
  324.   strcat (helpstr, buf);
  325.   mutt_make_help (buf, sizeof (buf), "To  ", MENU_COMPOSE, OP_COMPOSE_EDIT_TO);
  326.   strcat (helpstr, buf);
  327.   mutt_make_help (buf, sizeof (buf), "CC  ", MENU_COMPOSE, OP_COMPOSE_EDIT_CC);
  328.   strcat (helpstr, buf);
  329.   mutt_make_help (buf, sizeof (buf), "Subj  ", MENU_COMPOSE, OP_COMPOSE_EDIT_SUBJECT);
  330.   strcat (helpstr, buf);
  331.   mutt_make_help (buf,